package core.proto;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.TransferHandler;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import app.exceptions.CollabVizException;
import core.util.logging.SimpleLogger;
import core.util.logging.constants.Location;

public class FileTree extends JPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 5427196609258056804L;

	private static final SimpleLogger LOGGER = SimpleLogger.getLogger();

	public static final Color openFileNodeColor = new Color(255, 255, 150);
	public static final Color openFileNodeFocusedColor = Color.YELLOW;

	/** Search */
	protected static Color SEARCHED_NODE_BACKGROUND_COLOR = Color.LIGHT_GRAY;
	/** Construct a FileTree */
	/** Icons for closed directory folders */
	public static ImageIcon NONCASE_DIR_CLOSED;

	public static ImageIcon COLD_DIR_CLOSED;

	public static ImageIcon CURRENT_DIR_CLOSED;

	public static ImageIcon CURRENT_ALSPACH_DIR_CLOSED;

	public static ImageIcon CURRENT_MIDDLEBROOK_DIR_CLOSED;

	public static ImageIcon CURRENT_RAFFIELD_DIR_CLOSED;

	public static ImageIcon CURRENT_WILMORE_DIR_CLOSED;

	/** icons for open directory folders */
	public static ImageIcon NONCASE_DIR_OPEN;

	public static ImageIcon COLD_DIR_OPEN;

	public static ImageIcon CURRENT_DIR_OPEN;

	public static ImageIcon CURRENT_ALSPACH_DIR_OPEN;

	public static ImageIcon CURRENT_MIDDLEBROOK_DIR_OPEN;

	public static ImageIcon CURRENT_RAFFIELD_DIR_OPEN;

	public static ImageIcon CURRENT_WILMORE_DIR_OPEN;

	/** icons for closed case files */
	public static ImageIcon NONCASE_FILE_CLOSED;

	public static ImageIcon CURRENT_ALSPACH_FILE_CLOSED;

	public static ImageIcon CURRENT_MIDDLEBROOK_FILE_CLOSED;

	public static ImageIcon CURRENT_RAFFIELD_FILE_CLOSED;

	public static ImageIcon CURRENT_WILMORE_FILE_CLOSED;

	public static ImageIcon COLD_FORMAN_FILE_CLOSED;

	public static ImageIcon COLD_KASTANEK_FILE_CLOSED;

	public static ImageIcon COLD_WARING_FILE_CLOSED;

	public static ImageIcon COLD_FISK_FILE_CLOSED;

	public static ImageIcon COLD_MOELLER_FILE_CLOSED;

	public static ImageIcon COLD_STOKES_FILE_CLOSED;

	// public static ImageIcon RED_F;
	// public static ImageIcon BLUE_F;

	/** icons for open case files */
	public static ImageIcon NONCASE_FILE_OPEN;

	public static ImageIcon CURRENT_ALSPACH_FILE_OPEN;

	public static ImageIcon CURRENT_MIDDLEBROOK_FILE_OPEN;

	public static ImageIcon CURRENT_RAFFIELD_FILE_OPEN;

	public static ImageIcon CURRENT_WILMORE_FILE_OPEN;

	public static ImageIcon COLD_FORMAN_FILE_OPEN;

	public static ImageIcon COLD_KASTANEK_FILE_OPEN;

	public static ImageIcon COLD_WARING_FILE_OPEN;

	public static ImageIcon COLD_FISK_FILE_OPEN;

	public static ImageIcon COLD_MOELLER_FILE_OPEN;

	public static ImageIcon COLD_STOKES_FILE_OPEN;

	// public static ImageIcon OPENED_RED;
	// public static ImageIcon OPENED_BLUE;

	public JTree tree = null;
	public static SearchBar searchBar;

	public int window;

	public FileTree(File dir, final int window) {
		this.window = window;
		/** initialize icons for closed directory folders */
		NONCASE_DIR_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/greenfolder.png"));
		COLD_DIR_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/bluefolder.png"));
		CURRENT_DIR_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/redfolder.png"));
		CURRENT_ALSPACH_DIR_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/redfolder_shade1.png"));
		CURRENT_MIDDLEBROOK_DIR_CLOSED = new ImageIcon(this.getClass()
				.getResource("/img/redfolder_shade2.png"));
		CURRENT_RAFFIELD_DIR_CLOSED = new ImageIcon(this.getClass()
				.getResource("/img/redfolder_shade3.png"));
		CURRENT_WILMORE_DIR_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/redfolder_shade4.png"));

		/** initialize icons for open directory folders */
		NONCASE_DIR_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/opengreenfolder.png"));
		COLD_DIR_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openbluefolder.png"));
		CURRENT_DIR_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openredfolder.png"));
		CURRENT_ALSPACH_DIR_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openredfolder_shade1.png"));
		CURRENT_MIDDLEBROOK_DIR_OPEN = new ImageIcon(this.getClass()
				.getResource("/img/openredfolder_shade2.png"));
		CURRENT_RAFFIELD_DIR_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openredfolder_shade3.png"));
		CURRENT_WILMORE_DIR_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openredfolder_shade4.png"));

		/** initialize icons for closed case files */
		NONCASE_FILE_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/greenfile.png"));
		CURRENT_ALSPACH_FILE_CLOSED = new ImageIcon(this.getClass()
				.getResource("/img/redfile_shade1.png"));
		CURRENT_MIDDLEBROOK_FILE_CLOSED = new ImageIcon(this.getClass()
				.getResource("/img/redfile_shade2.png"));
		CURRENT_RAFFIELD_FILE_CLOSED = new ImageIcon(this.getClass()
				.getResource("/img/redfile_shade3.png"));
		CURRENT_WILMORE_FILE_CLOSED = new ImageIcon(this.getClass()
				.getResource("/img/redfile_shade4.png"));
		COLD_FORMAN_FILE_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/bluefile_shade1.png"));
		COLD_KASTANEK_FILE_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/bluefile_shade2.png"));
		COLD_WARING_FILE_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/bluefile_shade3.png"));
		COLD_FISK_FILE_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/bluefile_shade4.png"));
		COLD_MOELLER_FILE_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/bluefile_shade5.png"));
		COLD_STOKES_FILE_CLOSED = new ImageIcon(this.getClass().getResource(
				"/img/bluefile_shade6.png"));

		/** initialize icons for open case files */
		NONCASE_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/opengreen.png"));
		CURRENT_ALSPACH_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openred_shade1.png"));
		CURRENT_MIDDLEBROOK_FILE_OPEN = new ImageIcon(this.getClass()
				.getResource("/img/openred_shade2.png"));
		CURRENT_RAFFIELD_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openred_shade3.png"));
		CURRENT_WILMORE_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openred_shade4.png"));
		COLD_FORMAN_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openblue_shade1.png"));
		COLD_KASTANEK_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openblue_shade2.png"));
		COLD_WARING_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openblue_shade3.png"));
		COLD_FISK_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openblue_shade4.png"));
		COLD_MOELLER_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openblue_shade5.png"));
		COLD_STOKES_FILE_OPEN = new ImageIcon(this.getClass().getResource(
				"/img/openblue_shade6.png"));

		setLayout(new BorderLayout());

		// Make a tree list with all the nodes, and make it a JTree
		tree = new JTree(addNodes(null, dir, 0));
		tree.setDragEnabled(true);

		tree.getSelectionModel().setSelectionMode(
				TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
		tree.setTransferHandler(new FileTransferHandler());

		Vector<String> directorypath = new Vector();
		// icon rendering
		TreeCellRenderer renderer = new IconCellRenderer();
		tree.setCellRenderer(renderer);
		// tree.setCellRenderer( new CaseTreeCellRenderer() );
		ToolTipManager.sharedInstance().registerComponent(tree);

		// System.out.println( renderer.getClass() );

		/**
		 * add listener to tree for mouse click event, distinguish between
		 * single and double click
		 */
		tree.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				// for transferHandler
				JComponent comp = (JComponent) e.getSource();
				TransferHandler handler = comp.getTransferHandler();
				handler.exportAsDrag(comp, e, TransferHandler.COPY_OR_MOVE);

				int selRow = tree.getRowForLocation(e.getX(), e.getY());
				TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
				if (selPath != null) {
					DefaultMutableTreeNode node = (DefaultMutableTreeNode) selPath
							.getLastPathComponent();
					IconData icon = (IconData) node.getUserObject();
					CaseNode case_node = (CaseNode) icon.getObject();
					if (selRow != -1 && e.getClickCount() >= 2
							&& node.getUserObject() instanceof IconData) {
						if (node.isLeaf() != true) {
							// If isVisited was false, repaint with visited
							// set icons for nonleaf nodes
							if (case_node.isVisited() == false) {
								case_node.setVisited(true);
								icon.setIcon(icon.m_expandedIcon);
								AllComponents.canvas.repaint();
							}
						}
						if (node.isLeaf() == true) {
							// If isVisited was false, repaint with visited
							// icons
							if (case_node.isVisited() == false) {
								case_node.setVisited(true);
								icon.setIcon(icon.m_expandedIcon);
								AllComponents.canvas.repaint();
							}
							System.out.println("line 58 You selected leaf:"
									+ case_node.getAbsolutePath());
							try {
								LOGGER.log(case_node.toString(), Location.DS,
										"open file");
								try {
									AllComponents.fileTreeUpdateDoc(case_node,
											true, window);
								} catch (CollabVizException e1) {
									// TODO Auto-generated catch block
									e1.printStackTrace();
								}
							} catch (IOException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}
						} else {// 1 click
							if (node.isLeaf() == true) {
								// node.setVisited(true);
							}
						}
					}
				}
			}
		});

		// Lastly, put the JTree into a JScrollPane.
		JScrollPane scrollpane = new JScrollPane();
		scrollpane.getViewport().add(tree);
		add(BorderLayout.CENTER, scrollpane);
		// tree.setRootVisible(false);

		// SearchBar
		// SearchBar searchBar = new SearchBar( this );
		searchBar = new SearchBar(this);
		add(BorderLayout.SOUTH, searchBar);
		setSize(scrollpane.getX(), scrollpane.getY() + 100);
	}

	/** Add nodes from under "dir" into curTop. Highly recursive. */
	DefaultMutableTreeNode addNodes(DefaultMutableTreeNode curTop, File dir,
			int type) {
		String curPath = dir.getPath();// get file or folder path
		DefaultMutableTreeNode curDir;
		if (type == 0) {
			Font font = new Font("Courier New", Font.BOLD, 19);
			curDir = new DefaultMutableTreeNode(new IconData(
					NONCASE_DIR_CLOSED, NONCASE_DIR_OPEN, Color.GRAY, font,
					new CaseNode(dir.getName(), curPath, type)));
			System.out.println(curDir.toString());

		} else if (type == -1) {
			Font font = new Font("Courier New", Font.ITALIC, 12);
			ImageIcon closedIcon = getClosedColdDirIcon(dir.getName());
			ImageIcon openIcon = getOpenColdDirIcon(dir.getName());
			curDir = new DefaultMutableTreeNode(new IconData(closedIcon,
					openIcon, Color.GRAY, font, new CaseNode(dir.getName(),
							curPath, type)));
			System.out.println(curDir.toString());
		} else {
			Font font = new Font("Courier New", Font.ITALIC, 12);
			ImageIcon closedIcon = getClosedCurrentDirIcon(dir.getName());
			ImageIcon openIcon = getOpenCurrentDirIcon(dir.getName());
			curDir = new DefaultMutableTreeNode(new IconData(closedIcon,
					openIcon, Color.GRAY, font, new CaseNode(dir.getName(),
							curPath, type)));
		}

		if (curTop != null) { // should only be null at root
			curTop.add(curDir); // add node representing current path
		}
		Vector ol = new Vector();
		// this only gives the cannonial name of file/dir
		String[] tmp = dir.list();
		for (int i = 0; i < tmp.length; i++) {
			ol.addElement(tmp[i]);
			// System.out.println( "line 82:" + tmp[i] );
		}
		Collections.sort(ol, String.CASE_INSENSITIVE_ORDER);
		File f;
		Vector files = new Vector();
		// Make two passes, one for Dirs and one for Files. This is #1.
		for (int i = 0; i < ol.size(); i++) {
			// thisObject is a string
			String thisObject = (String) ol.elementAt(i);
			String newPath;
			if (curPath.equals(".")) { // current directory
				// newPath starts from the current directory
				newPath = thisObject;
			} else {
				// new path to the next lv of dir/file
				newPath = curPath + File.separator + thisObject;
			}
			if ((f = new File(newPath)).isDirectory()) {
				if (f.getName().toLowerCase().contains("COLD".toLowerCase())) {
					// System.out.println("line 98:"+curDir);
					addNodes(curDir, f, -1);// can change to diff folders if
					// really needed...
				} else if (f.getName().toLowerCase().contains(
						"CURRENT".toLowerCase())) {
					addNodes(curDir, f, 1);
				} else {
					addNodes(curDir, f, 0);
				}
			} else {
				// files in current dir added to "files" vector
				files.addElement(thisObject);
			}
		}
		// Pass two: for files.
		for (int fnum = 0; fnum < files.size(); fnum++) {
			String name = files.elementAt(fnum).toString();
			File currentDir = new File(curPath);
			if (currentDir.getName().toLowerCase().contains(
					"COLD".toLowerCase())) {
				Font font = new Font("Courier New", Font.ITALIC, 12);
				ImageIcon closedIcon = getClosedColdFileIcon(name);
				ImageIcon openIcon = getOpenColdFileIcon(name);
				curDir.add(new DefaultMutableTreeNode(new IconData(closedIcon, // BLUE_F,
						openIcon, Color.GRAY, font, new CaseNode(files
								.elementAt(fnum).toString(), curPath
								+ File.separator + name, -1))));
			} else if (currentDir.getName().toLowerCase().contains(
					"CURRENT".toLowerCase())) {
				Font font = new Font("Courier New", Font.ITALIC, 12);
				ImageIcon closedIcon = getClosedCurrentFileIcon(currentDir
						.getName());
				ImageIcon openIcon = getOpenCurrentFileIcon(currentDir
						.getName());
				curDir.add(new DefaultMutableTreeNode(new IconData(closedIcon, // RED_F,
						openIcon, Color.GRAY, font, new CaseNode(files
								.elementAt(fnum).toString(), curPath
								+ File.separator + name, 1))));
			} else {
				Font font = new Font("Courier New", Font.ITALIC, 12);
				curDir.add(new DefaultMutableTreeNode(new IconData(
						NONCASE_FILE_CLOSED, NONCASE_FILE_OPEN, Color.GRAY,
						font, new CaseNode(files.elementAt(fnum).toString(),
								curPath + File.separator + name, 0))));
			}
		}
		return curDir;
	}

	private ImageIcon getClosedColdDirIcon(String name) {
		ImageIcon icon = COLD_DIR_CLOSED;
		return icon;
	}

	private ImageIcon getOpenColdDirIcon(String name) {
		ImageIcon icon = COLD_DIR_OPEN;
		return icon;
	}

	private ImageIcon getClosedCurrentDirIcon(String name) {
		ImageIcon icon = null;
		if (name.toLowerCase().contains("alspach current"))
			icon = CURRENT_ALSPACH_DIR_CLOSED;
		else if (name.toLowerCase().contains("middlebrook current"))
			icon = CURRENT_MIDDLEBROOK_DIR_CLOSED;
		else if (name.toLowerCase().contains("raffield current"))
			icon = CURRENT_RAFFIELD_DIR_CLOSED;
		else if (name.toLowerCase().contains("wilmore current"))
			icon = CURRENT_WILMORE_DIR_CLOSED;
		else if (name.toLowerCase().contains("current"))
			icon = CURRENT_DIR_CLOSED;
		else
			;
		return icon;
	}

	private ImageIcon getOpenCurrentDirIcon(String name) {
		ImageIcon icon = null;
		if (name.toLowerCase().contains("alspach current"))
			icon = CURRENT_ALSPACH_DIR_OPEN;
		else if (name.toLowerCase().contains("middlebrook current"))
			icon = CURRENT_MIDDLEBROOK_DIR_OPEN;
		else if (name.toLowerCase().contains("raffield current"))
			icon = CURRENT_RAFFIELD_DIR_OPEN;
		else if (name.toLowerCase().contains("wilmore current"))
			icon = CURRENT_WILMORE_DIR_OPEN;
		else if (name.toLowerCase().contains("current"))
			icon = CURRENT_DIR_OPEN;
		else
			;
		return icon;
	}

	private ImageIcon getClosedColdFileIcon(String name) {
		ImageIcon icon = null;
		if (name.toLowerCase().contains("forman"))
			icon = COLD_FORMAN_FILE_CLOSED;
		else if (name.toLowerCase().contains("kastanek"))
			icon = COLD_KASTANEK_FILE_CLOSED;
		else if (name.toLowerCase().contains("waring"))
			icon = COLD_WARING_FILE_CLOSED;
		else if (name.toLowerCase().contains("fisk"))
			icon = COLD_FISK_FILE_CLOSED;
		else if (name.toLowerCase().contains("moeller"))
			icon = COLD_MOELLER_FILE_CLOSED;
		else if (name.toLowerCase().contains("stokes"))
			icon = COLD_STOKES_FILE_CLOSED;
		else
			;
		return icon;
	}

	private ImageIcon getOpenColdFileIcon(String name) {
		ImageIcon icon = null;
		if (name.toLowerCase().contains("forman"))
			icon = COLD_FORMAN_FILE_OPEN;
		else if (name.toLowerCase().contains("kastanek"))
			icon = COLD_KASTANEK_FILE_OPEN;
		else if (name.toLowerCase().contains("waring"))
			icon = COLD_WARING_FILE_OPEN;
		else if (name.toLowerCase().contains("fisk"))
			icon = COLD_FISK_FILE_OPEN;
		else if (name.toLowerCase().contains("moeller"))
			icon = COLD_MOELLER_FILE_OPEN;
		else if (name.toLowerCase().contains("stokes"))
			icon = COLD_STOKES_FILE_OPEN;
		else
			;
		return icon;
	}

	private ImageIcon getClosedCurrentFileIcon(String name) {
		ImageIcon icon = null;
		if (name.toLowerCase().contains("alspach current"))
			icon = CURRENT_ALSPACH_FILE_CLOSED;
		else if (name.toLowerCase().contains("middlebrook current"))
			icon = CURRENT_MIDDLEBROOK_FILE_CLOSED;
		else if (name.toLowerCase().contains("raffield current"))
			icon = CURRENT_RAFFIELD_FILE_CLOSED;
		else if (name.toLowerCase().contains("wilmore current"))
			icon = CURRENT_WILMORE_FILE_CLOSED;
		else
			;
		return icon;
	}

	private ImageIcon getOpenCurrentFileIcon(String name) {
		ImageIcon icon = null;
		if (name.toLowerCase().contains("alspach current"))
			icon = CURRENT_ALSPACH_FILE_OPEN;
		else if (name.toLowerCase().contains("middlebrook current"))
			icon = CURRENT_MIDDLEBROOK_FILE_OPEN;
		else if (name.toLowerCase().contains("raffield current"))
			icon = CURRENT_RAFFIELD_FILE_OPEN;
		else if (name.toLowerCase().contains("wilmore current"))
			icon = CURRENT_WILMORE_FILE_OPEN;
		else
			;
		return icon;
	}

	public Dimension getMinimumSize() {
		return new Dimension(100, 560);
	}

	public Dimension getPreferredSize() {
		return new Dimension(100, 560);
	}

	// Returns a TreePath containing the specified node.
	public TreePath getPath(DefaultMutableTreeNode node) {
		List list = new ArrayList();
		// Add all nodes to list
		while (node != null) {
			list.add(node);
			node = (DefaultMutableTreeNode) node.getParent();
		}
		Collections.reverse(list);

		// Convert array of nodes to TreePath
		return new TreePath(list.toArray());
	}

	public void expandTree(DefaultMutableTreeNode node) {
		// collapseTree();
		TreeNode[] nodes = ((DefaultTreeModel) tree.getModel())
				.getPathToRoot(node);
		TreePath treePath = new TreePath(nodes);
		tree.setSelectionPath(treePath);
		tree.scrollPathToVisible(treePath);
		// make sure all files now have open icon
		for (int i = 0; i < nodes.length; i++) {
			// make all ancestor nodes use expanded icons in the loop, but not
			// working...
			DefaultMutableTreeNode thisnode = (DefaultMutableTreeNode) nodes[i];
			System.out.println("next node in tree path is: "
					+ thisnode.toString());
			IconData icon = (IconData) thisnode.getUserObject();
			CaseNode case_node = (CaseNode) icon.getObject();
			case_node.setVisited(true);
			icon.setIcon(icon.m_expandedIcon);
		}
		AllComponents.canvas.repaint();
		// DefaultMutableTreeNode ancestor=
		// (DefaultMutableTreeNode)treePath.getLastPathComponent();
		// IconData icon = (IconData) node.getUserObject();
		// CaseNode case_node = (CaseNode) icon.getObject();
		// case_node.setVisited( true );
		// icon.setIcon( icon.m_expandedIcon );
		// AllComponents.canvas.repaint();
	}

	public void collapseTree() {
		int rowCount = tree.getRowCount() - 1;
		while (rowCount >= 0) {
			tree.collapseRow(rowCount);
			rowCount--;
		}
	}

	/**
	 * This method takes the node string and traverses the tree till it finds
	 * the node matching the string. If the match is found the node is returned
	 * else null is returned
	 * 
	 * @param rotateViz
	 *            TODO
	 * @param nodeStr
	 *            node string to search for
	 * 
	 * @return tree node
	 */
	public void expandTreeByPath(String absPath, boolean rotateViz) {

		// Get the enumeration
		Enumeration e = ((DefaultMutableTreeNode) tree.getModel().getRoot())
				.breadthFirstEnumeration();
		// iterate through the enumeration
		while (e.hasMoreElements()) {
			// System.out.println(" ------------ expand Tree by Path
			// --------------------- level 02");
			DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) e
					.nextElement();
			IconData icon = (IconData) treeNode.getUserObject();
			CaseNode node = (CaseNode) icon.getObject();
			String filePath = ((CaseNode) node).getAbsolutePath();
			filePath = filePath.replace('/', '\\');
			if (filePath.equals(AllComponents.getPreviousPath())) {
				// node.setVisited( false );
				icon.m_backgroudColor = openFileNodeColor;
				continue;
			}
			if (filePath.equals(absPath)) {

				System.out.println("absPath = " + absPath);
				System.out.println("getAbsolutePath = " + filePath);
				icon.m_backgroudColor = openFileNodeFocusedColor;
				this.expandTree(treeNode);
				try {
					AllComponents.fileTreeUpdateDoc(node, true, window,
							rotateViz);
				} catch (IOException e1) {
					e1.printStackTrace();
				} catch (CollabVizException e1) {
					e1.printStackTrace();
				}
			} else {
				// if (icon.m_icon.equals(icon.m_expandedIcon) && node.isLeaf())
				// {
				// icon.m_backgroudColor = openFileNodeColor;
				// } else {
				// icon.m_backgroudColor = Color.WHITE;
				// }
			}
		}
		tree.repaint();
	}

	public void treeNodeClosedByPath(String absPath) {
		// Get the enumeration
		// System.out.println( "----------treeNodeClosedByPath absPath = " +
		// absPath );
		Enumeration e = ((DefaultMutableTreeNode) tree.getModel().getRoot())
				.breadthFirstEnumeration();
		// iterate through the enumeration
		DefaultMutableTreeNode treeNode = null;
		IconData icon = null;
		CaseNode node = null;
		while (e.hasMoreElements()) {
			treeNode = (DefaultMutableTreeNode) e.nextElement();
			icon = (IconData) treeNode.getUserObject();
			node = (CaseNode) icon.getObject();
			String filePath = ((CaseNode) node).getAbsolutePath();
			filePath = filePath.replace('/', '\\');
			if (filePath.equals(absPath)) {
				break;
			}
		}
		// node.setVisited( false );
		System.out.println("----------treeNodeClosedByPath node file = "
				+ node.toString());
		// icon.setIcon( icon.m_closedIcon );
		icon.m_backgroudColor = Color.WHITE;
		// tree.collapsePath(this.getPath(treeNode));
		tree.repaint();
	}

	/**
	 * To remember the tree current expanded status before searching Use it to
	 * return the tree to its original status after searching
	 */
	private List<Integer> savedExpandedRows = null;

	public List<Integer> getSavedExpandedRows() {
		return savedExpandedRows;
	}

	public void saveTreeExpandedStatus() {
		savedExpandedRows = new ArrayList<Integer>();
		int rowCount = tree.getRowCount() - 1;
		for (int index = 0; index < rowCount; index++) {
			if (!tree.isCollapsed(index)) {
				savedExpandedRows.add(new Integer(index));
			}
		}
	}

	public void restoreExpandedTreeStatus() {
		if (savedExpandedRows == null)
			return;

		for (Integer row : savedExpandedRows) {
			// System.out.println("row.intValue() = " + row.intValue());
			tree.expandRow(row.intValue());
		}
		expandTreeByPath(AllComponents.getCurrentPath(), false);
	}

	public static SearchBar getSearchBar() {
		return searchBar;
	}

	/** Main: make a Frame, add a FileTree */
	public static void main(String[] args) {

		JFrame frame = new JFrame("FileTree");
		frame.setForeground(Color.black);
		frame.setBackground(Color.lightGray);
		Container cp = frame.getContentPane();

		if (args.length != 1) {
			// load directory from SK Experiment Materials
			// cp.add(new FileTree(new File(".")));
			// cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS));
			cp
					.add(new FileTree(
							new File(
									"C:/Documents and Settings/Si Chang/My Documents/meng trunk 0421/meng trunk/src/data/files"),
							1));

		} else {
			cp.add(new FileTree(new File(args[0]), 1));
		}

		frame.pack();
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

}